package com.lmf.annotation.bean;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;

import java.util.Arrays;

/**
 * @Aspect：告诉Spring当前类是一个切面类，而不是一些其他普通的类
 */
@Aspect
public class LogAspects {

    //公共通知
//    @Pointcut("execution(public int com.lmf.annotation.bean.MathCalculator.div(..))")
    @Pointcut("execution(public int com.lmf.annotation.bean.MathCalculator.div(..))")
    public void pointcut(){

    }

    /**
     * JoinPoint:切入点的对象，即，实际被增强的方法；若出现，就一定要出现在参数第一位，否则不生效
     * @param joinPoint
     */
    //前置通知
//    @Before("execution(public int com.lmf.annotation.bean.MathCalculator.div(..))")
    @Before("pointcut()")
    public void before(JoinPoint joinPoint){
        Object[] args = joinPoint.getArgs();
        System.out.println("前置通知。。。before。。。。;"+"获取切入点的方法名："+
                joinPoint.getSignature().getName()+"参数表："+ Arrays.toString(args));
    }

    //最终通知：即使异常也会执行
//    @After("execution(public int com.lmf.annotation.bean.MathCalculator.div(..))")
    @After("execution(public int com.lmf.annotation.bean.MathCalculator.div(..))")
    public void after(){
        System.out.println("最终通知。。。after。。。。");
    }

    /**
     * returning:封装原方法的返回值,会受@Around注解影响
     * @param result
     */
    //后置通知
    @AfterReturning(value = "execution(public int com.lmf.annotation.bean.MathCalculator.div(..))",returning = "result")
    public void afterReturn(Object result){
        System.out.println("后置通知。。。AfterReturning。。。。"+result);
    }

    /**
     * throwing:表示抛出的异常
     * @param exception
     */
    //异常通知
    @AfterThrowing(value = "execution(public int com.lmf.annotation.bean.MathCalculator.div(..))",throwing = "exception")
    public void afterThrowing(Exception exception){
        System.out.println("异常通知。。。AfterThrowing。。。。");
    }

    //环绕通知
    @Around("execution(public int com.lmf.annotation.bean.MathCalculator.div(..))")
    public int around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕通知之前。。。Around。。。。");
        proceedingJoinPoint.proceed();//执行被增强的方法
        System.out.println("环绕通知之后。。。Around。。。。");
        return 0;
    }

}
